package com.betterjr.modules.temhandler.service;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.betterjr.common.service.BaseService;
import com.betterjr.common.utils.BTAssert;
import com.betterjr.common.utils.Collections3;
import com.betterjr.common.utils.QueryTermBuilder;
import com.betterjr.common.utils.UserUtils;
import com.betterjr.mapper.pagehelper.Page;
import com.betterjr.modules.temhandler.dao.TemDataMapper;
import com.betterjr.modules.temhandler.data.TemDataConstant;
import com.betterjr.modules.temhandler.data.TemRelationConstant;
import com.betterjr.modules.temhandler.entity.TemData;
import com.google.common.collect.Lists;

/**
 * 
 * @ClassName: TemDataService 
 * @Description: 临时数据Service
 * @author xuyp
 * @date 2018年1月9日 下午2:52:39 
 *
 */
@Service
public class TemDataService extends BaseService<TemDataMapper, TemData> {

    @Autowired
    private TemHandlerConfigService configService;

    @Autowired
    private TemBusinRelationService relationService;

    /**
     *  在配置中心中配置了必填属性和申请就生效的信息必须填写。否则报错
     * @Title: saveAddTemData 
     * @Description: 新增或者编辑临时记录 
     * @param anTemData
     * @return 新增临时记录 
     * @throws 
     * @author xuyp
     * @date 2017年12月21日 上午10:23:47
     */
    public TemData saveAddTemData(TemData anTemData) {

        // 去配置中心 校验数据
        checkVerfiyData(anTemData);

        // 去关系配置中封装查询条件
        relationService.packageQueryProperties(anTemData);

        boolean addFlag = true;
        List<TemData> temDataList = queryTemData(anTemData.getBusinTableType(), anTemData.getBusinTableId(), "0,1,2,3");
        if (Collections3.isEmpty(temDataList)) {
            anTemData.saveAddInitValue(1);

        } else {
            for (TemData temData : temDataList) {
                if (!(temData.getBusinStatus().equals(TemDataConstant.TEMDATA_BUSINSTATUS_INSERTED)
                        || temData.getBusinStatus().equals(TemDataConstant.TEMDATA_BUSINSTATUS_TEMTABLEINSERT))) {
                    BTAssert.notNull(null, "当前数据已经复核,操作失败");
                }
                temData.setBusinStatus(TemDataConstant.TEMDATA_BUSINSTATUS_DELETED);
                temData.setLaster(TemDataConstant.TEMDATA_LASTER_NO);
                this.updateByPrimaryKeySelective(temData);
            }
            BTAssert.isTrue(
                    Collections3.getFirst(temDataList).getBusinTableOperorg().equals(anTemData.getBusinTableOperorg()),
                    "你没有当前数据的操作权限,操作失败");
            anTemData.saveAddInitValue(Collections3.getFirst(temDataList).getVersion() + 1);

            // 设置上一手 id
            addFlag = false;
        }
        setEffectivePrifexId(anTemData);
        this.insertSelective(anTemData);

        // 调用数据插入回调接口
        configService.saveSynchronizedAddBusin(anTemData, addFlag);
        return anTemData;
    }

    /**
     * 
     * @Title: saveDeleteTemData 
     * @Description: 删除临时数据
     * @param anId
     * @param anDescription
     * @return 删除临时数据
     * @throws 
     * @author xuyp
     * @date 2017年12月25日 下午3:16:01
     */
    public TemData saveDeleteTemData(Long anId, String anDescription) {

        BTAssert.notNull(anId, "查询条件为空,操作失败");

        TemData temData = this.selectByPrimaryKey(anId);
        BTAssert.notNull(temData, "未查到相关记录,操作失败");
        if (TemDataConstant.TEMDATA_BUSINSTATUS_DELETED.equals(temData.getBusinStatus())) {
            return temData;
        }
        BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_EFFECTIVE.equals(temData.getBusinStatus()),
                "当前数据已经生效,操作失败");
        BTAssert.isTrue(UserUtils.getOperatorInfo().getOperOrg().equals(temData.getBusinTableOperorg())
                || UserUtils.platformUser(), "你没有操作权限,操作失败");

        // 同步删除业务表中的数据
        configService.saveSynchronizedDeleteBusin(temData);
        // 针对临时数据处理
        if (TemDataConstant.TEMDATA_BUSINSTATUS_TEMTABLEINSERT.equals(temData.getBusinStatus())) {
            this.deleteByPrimaryKey(anId);
            return temData;
        }
        temData.setLaster(TemDataConstant.TEMDATA_LASTER_NO);
        temData.setBusinStatus(TemDataConstant.TEMDATA_BUSINSTATUS_DELETED);
        this.updateByPrimaryKeySelective(temData);
        return temData;
    }

    /**
     * 
     * @Title: saveUpdateTemDataStatus 
     * @Description: 修改临时数据的状态 
     * @param ids
     * @param anBusinStatus
     * @return List<TemData>
     * @throws 
     * @author xuyp
     * @date 2018年1月4日 下午5:29:42
     */
    public List<TemData> saveUpdateTemDataStatus(String ids, String anBusinStatus) {

        BTAssert.isTrue(StringUtils.isNoneBlank(ids), "操作条件为空,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anBusinStatus), "条件为空,操作失败");
        List<Long> idList = convertToList(ids);
        if (!Collections3.isEmpty(idList)) {
            List<TemData> temDataList = new ArrayList<>(idList.size());
            for (Long id : idList) {
                TemData data = this.selectByPrimaryKey(id);
                BTAssert.notNull(data, "主键" + id + "为空,操作失败");
                BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_EFFECTIVE.equals(data.getBusinStatus()),
                        "当前数据已经生效,操作失败");
                BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_DELETED.equals(data.getBusinStatus()),
                        "当前数据已经失效,操作失败");
                BTAssert.isTrue(UserUtils.getOperatorInfo().getOperOrg().equals(data.getBusinTableOperorg())
                        || UserUtils.platformUser(), "你没有操作权限,操作失败");
                data.setBusinStatus(anBusinStatus);
                this.updateByPrimaryKeySelective(data);
                temDataList.add(data);
            }
            return temDataList;
        }

        return Lists.newArrayList();
    }

    /**
     * 
     * @Title: saveAuditTemData 
     * @Description: 审核临时数据 
     * @param anId
     * @param anDescription
     * handlerResult   1处理成功  9处理失败
     * @return 审核临时数据
     * @throws 
     * @author xuyp
     * @date 2017年12月25日 下午5:34:39
     */
    public TemData saveAuditTemData(Long anId, String anDescription, Map<String, Object> anMap) {

        BTAssert.notNull(anId, "查询条件为空,操作失败");
        BTAssert.notNull(anMap, "查询条件为空,操作失败");
        BTAssert.notNull(anMap.get("handlerResult"), "复核结果为空,操作失败");

        TemData temData = this.selectByPrimaryKey(anId);
        BTAssert.notNull(temData, "未查到相关记录,操作失败");
        BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_DELETED.equals(temData.getBusinStatus()), "当前数据已经失效,操作失败");
        BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_EFFECTIVE.equals(temData.getBusinStatus()),
                "当前数据已经生效,操作失败");
        BTAssert.isTrue(!TemDataConstant.TEMDATA_BUSINSTATUS_TEMTABLEINSERT.equals(temData.getBusinStatus()),
                "当前数据未提交申请,操作失败");
        BTAssert.isTrue(UserUtils.getOperatorInfo().getOperOrg().equals(temData.getBusinTableOperorg())
                || UserUtils.platformUser(), "你没有操作权限,操作失败");

        // temData.setDescription(anDescription);
        temData.saveAuditValue(UserUtils.getOperatorInfo(), anDescription, anMap.get("handlerResult").toString());

        // 同步复核操作 如果设置步骤复核直接生效会自动生效数据并且修改状态
        configService.saveSynchronizedCheckOrAudit(temData, anMap);

        this.updateByPrimaryKeySelective(temData);
        return temData;
    }

    /**
     * 
     * @Title: queryTemData 
     * @Description: 根据表类型和表主键查询 临时数据
     * @param anClassUrl
     * @param anBusinTableId
     * @param anBusinStatus  状态1刚插入  2已复核  3已审核   4 生效 9删除
     * @return 根据表类型和表主键查询 临时数据
     * @throws 
     * @author xuyp
     * @date 2017年12月25日 下午2:10:31
     */
    @SuppressWarnings("unchecked")
    public List<TemData> queryTemData(String anClassUrl, String anBusinTableId, String anBusinStatus) {

        Map<String, Object> map = QueryTermBuilder.newInstance().build();

        if (StringUtils.isNoneBlank(anClassUrl)) {
            map.put("businTableType", anClassUrl);
        } else {
            BTAssert.notNull(null, "类路径为空,查询失败");
        }

        if (StringUtils.isNoneBlank(anBusinTableId)) {
            map.put("businTableId", anBusinTableId);
        }

        if (StringUtils.isBlank(anBusinStatus)) {
            anBusinStatus = "1,2,3,4";
        }

        if (anBusinStatus.contains(TemRelationConstant.SYSTEM_FILE_SPAREATOR)) {

            map.put("businStatus", anBusinStatus.split(TemRelationConstant.SYSTEM_FILE_SPAREATOR));
        } else {
            map.put("businStatus", anBusinStatus);
        }

        return this.selectByProperty(map, "id Desc");
    }

    /**
     * 
     * @Title: queryTemData 
     * @Description: 分页查询 临时数据
     * @param anClassUrl  业务类全路径
     * @param anBusinStatus 状态  多个状态用,隔开
     * @param anQueryMap 前端传递的查询条件，参数可以传递业务中的参数（需要提前建立了映射）和temData的属性
     * @param anFlag 1 查询总条数
     * @param anPageNum 当前页数
     * @param anPageSize 每页显示的数量
     * @return TemData
     * @throws 
     * @author xuyp
     * @date 2017年12月28日 上午11:51:27
     */
    @SuppressWarnings("unchecked")
    public Page<TemData> queryTemData(String anClassUrl, String anBusinStatus, Map<String, Object> anQueryMap,
            String anFlag, int anPageNum, int anPageSize) {

        if (StringUtils.isBlank(anClassUrl)) {
            if (!UserUtils.platformUser()) {

                BTAssert.notNull(null, "类路径为空,查询失败");
            }
        }

        // 过滤空的
        anQueryMap = Collections3.filterMapEmptyObject(anQueryMap);

        //// 过滤TemConfig配置关系的条件
        Map<String, Object> map = relationService.convertQueryMap(anClassUrl, anQueryMap);

        // 过滤TemData本身的属性的查询条件
        map.putAll(Collections3.filterMap(anQueryMap, convertReflectFields()));

        if (StringUtils.isNotBlank(anClassUrl)) {
            map.put("businTableType", anClassUrl);
        }
        map = Collections3.fuzzyMap(map);
        if (StringUtils.isBlank(anBusinStatus)) {
            anBusinStatus = "1,2,3,4";
        }

        if (anBusinStatus.contains(TemRelationConstant.SYSTEM_FILE_SPAREATOR)) {

            map.put("businStatus", anBusinStatus.split(TemRelationConstant.SYSTEM_FILE_SPAREATOR));
        } else {
            map.put("businStatus", anBusinStatus);
        }

        return this.selectPropertyByPage(map, anPageNum, anPageSize, "1".equals(anFlag), "id desc");
    }

    /**
     * 
     * @Title: findTemDataByid 
     * @Description: 根据主键查询临时数据 
     * @param id
     * @return 根据主键查询临时数据 
     * @throws 
     * @author xuyp
     * @date 2017年12月26日 上午9:30:38
     */
    public TemData findTemDataByid(Long id) {
        BTAssert.notNull(id, "查询条件为空,查询失败");
        TemData data = this.selectByPrimaryKey(id);
        if (data == null) {
            return new TemData();
        }
        // BTAssert.notNull(data, "查询数据为空,查询失败");
        return data;
    }

    private String[] convertReflectFields() {

        Field[] fields = TemData.class.getDeclaredFields();
        String[] fieldsName = new String[fields.length * 4];
        for (int i = 0; i < fields.length; i++) {
            fieldsName[i * 4] = fields[i].getName();
            fieldsName[i * 4 + 1] = "LIKE" + fields[i].getName();
            fieldsName[i * 4 + 2] = "GTE" + fields[i].getName();
            fieldsName[i * 4 + 3] = "LTE" + fields[i].getName();
        }
        return fieldsName;
    }

    private TemData setEffectivePrifexId(TemData anTemData) {

        if (anTemData != null && StringUtils.isNoneBlank(anTemData.getBusinTableType())
                && StringUtils.isNotBlank(anTemData.getBusinTableId())) {
            List<TemData> list = queryTemData(anTemData.getBusinTableType(), anTemData.getBusinTableId(),
                    TemDataConstant.TEMDATA_BUSINSTATUS_EFFECTIVE);
            if (!Collections3.isEmpty(list)) {
                anTemData.setPrefixId(Collections3.getFirst(list).getId());
            }
        }

        return anTemData;
    }

    private List<Long> convertToList(String ids) {
        if (StringUtils.isNoneBlank(ids)) {
            List<Long> idList = new ArrayList<>();
            if (ids.contains(TemRelationConstant.SYSTEM_FILE_SPAREATOR)) {
                String[] split = ids.split(TemRelationConstant.SYSTEM_FILE_SPAREATOR);
                for (String string : split) {
                    try {
                        idList.add(Long.parseLong(string));
                    }
                    catch (Exception e) {
                        logger.info("convertToList 转换主键出错" + e.getMessage());
                    }
                }
            } else {
                try {
                    idList.add(Long.parseLong(ids));
                }
                catch (Exception e) {
                    logger.info("convertToList 转换主键出错" + e.getMessage());
                }
            }

            return idList;
        }
        return null;
    }

    /**
     * 
     * @Title: checkVerfiyData 
     * @Description: 校验数据
     * @param anTemData 校验数据
     * @throws 
     * @author xuyp
     * @date 2017年12月21日 上午10:35:03
     */
    private TemData checkVerfiyData(TemData anTemData) {

        BTAssert.notNull(anTemData, "数据为空,操作失败");
        String businTableType = anTemData.getBusinTableType();
        BTAssert.isTrue(StringUtils.isNoneBlank(businTableType), "请绑定数据类型,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anTemData.getBusinTableData()), "业务数据为空,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anTemData.getBusinTableOperorg()), "所属机构为空,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anTemData.getBusinTableId()), "业务主键为空,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anTemData.getCustNo() + ""), "企业编号为空,操作失败");
        BTAssert.isTrue(StringUtils.isNoneBlank(anTemData.getCustName()), "企业名称为空,操作失败");

        // 过滤日期的-
        anTemData.setBusinTableData(anTemData.getBusinTableData().replaceAll("-", ""));
        // 校验配置
        configService.checkVerfiyData(anTemData);

        return anTemData;

    }

}
